<template>
  <div class="container">
    <div class="content">
      <div class="elTreeClass">
        <el-tree
          ref="tree"
          :data="treeData"
          node-key="nodePath"
          :props="defaultProps"
          highlight-current
          default-expand-all
          show-checkbox
          :check-strictly="false"
          :expand-on-click-node="false"
          :render-content="renderContent"
          @check="handleCheck"
          @node-click="handleNodeClick"
        >
        </el-tree>
      </div>
      <div class="elTableClass">
      <!-- <el-table
            :data="selectedNodes"
            style="width: 100%"
            :row-key="idKey"
            :default-expand-all="true"
            border
          >
        <el-table-column
          v-for="(col, index) in columns"
          :key="index"
          :prop="col.prop"
          :label="col.label"
          :show-overflow-tooltip="true"
        >
          <template v-slot="{ row }">
            <el-input v-if="col.type === 'input'" v-model="row[col.prop]"></el-input>
            <el-checkbox v-else-if="col.type === 'checkbox'" v-model="row[col.prop]"></el-checkbox>
            <el-select v-else-if="col.type === 'select'" v-model="row[col.prop]" placeholder="请选择">
              <el-option
                v-for="item in col.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
            <span v-else>{{ row[col.prop] }}</span>
          </template>
        </el-table-column>
        
      </el-table> -->
      <!-- <div v-if="selectedNodes.length > 0">
        <h3>选中的节点及其父节点:</h3>
        <div>
          {{ selectedNodes }}
        </div>
      </div> -->

      </div>
    </div>
  </div>
</template>

<script>
// import { keyFor } from 'core-js/fn/symbol';

// import { nanoid } from 'nanoid'; // 引入 nanoid 库生成全局唯一的 ID
export default {
  name: 'checkBoxDemo',
  data() {
    return {
      defaultProps: {
        children: 'children',//指定子节点属性名
        label: 'name',// 指定节点标签的属性名
        checked: 'checked',
        code: 'code',
        type:'type',
        // id: 'id'  // 使用 `id` 作为唯一标识符
      },
      treeData: [
        {
          nodePath:'parent',
          code: 'parent',
          name: 'request标识',
          type: 'object',
          required: '1',
          level: "1",
          children: [
            {
              nodePath:'parent.child1',
              level: "2",
              code: 'child1',
              name: '我是child1我是child1我是child1我是child1我是child1',
              required: '0',
              type: 'string',
              children: null,
            },
            {
              nodePath:'parent.child2',
              code: 'child2',
              name: 'child2',
              level: "2",
              required: '0',
              type: 'string',
              children: [
                {
                  nodePath:'parent.child2.child2-1',
                  code: 'child2-1',
                  name: 'child2-1',
                  level: "3",
                  required: '0',
                  type: 'string',
                  children: null,
                  parentId: 'child2'
                },
                {
                  nodePath:'parent.child2.child2-2',
                  code: 'child2-2',
                  name: 'child2-2',
                  level: "3",
                  required: '0',
                  type: 'string',
                  children: null,
                  parentId: 'child2'
                },
                {
                  nodePath:'parent.child2.child2-3',
                  code: 'child2-3',
                  name: 'child2-3',
                  level: "3",
                  required: '0',
                  type: 'string',
                  children: null,
                  parentId: 'child2'
                }
              ],
            },
            {
              nodePath:'parent.child3',
              code: 'child3',
              name: 'child3',
              required: '0',
              type: 'string',
              level: "2",
              children: [
                {
                  nodePath:'parent.child3.child3-1',
                  code: 'child3-1',
                  name: 'child3-1',
                  level: "3",
                  required: '1',
                  type: 'string',
                  children: [
                    {
                      nodePath:'parent.child3.child3-1.child3-1-1',
                      code: 'child3-1-1',
                      name: 'child3-1-1',
                      required: '1',
                      type: 'string',
                      children: null,
                      parentId: 'child3-1',
                      level: "4",
                    }
                  ],
                }
              ],
            },
            {
              nodePath:'parent.child4',
              code: 'child4',
              name: 'child4',
              required: '0',
              type: 'string',
              children: null,
              level: "2",
            }
          ],
        }
      ],
      processedTreeData: [],  // 处理后的数据
      selectedNodes: [], // 存储选中的节点数据

      columns: [
        { prop: 'name', label: '参数名称', type: 'text' },
        { prop: 'required', label: '必填', type: 'checkbox' , width: 55,
          render: (h, params) => {
            // console.log('h',h);
            // console.log('params',params);
            
            const row = params.row;
            return h('el-checkbox', {
              props: {
                modelValue: row.required === '1'
              },
              on: {
                change: (value) => {
                  this.handleCheckboxChange(row, value);
                }
              }
            });
          }
        },
        { prop: 'maxLen', label: '最大长度', type: 'input'},
        { prop: 'checkRule', label: '校验规则', type: 'selection', options: [{ value: '1', label: '规则1' }, { value: '2', label: '规则2' }] },
        // { prop: 'checkRule', label: '填充规则', type: 'selection', options: [{ value: '1', label: '规则1' }, { value: '2', label: '规则2' }] }

      
      ],
      idKey: 'id',

      leftBoxWidth:0,
      tooltipText: '',
      showTooltip: false,
      currentTooltipNode: null,//记录当前节点
      tooltipPosition: { x: 0, y: 0 },
      newTree: [],
      isVisit : {},
      ret: {},
      visitObj: {},
      newTree: {},
      leafNodes: ["parent.child1", "parent.child2.child2-1", "parent.child2.child2-2", "parent.child2.child2-3", "parent.child3.child3-1.child3-1-1", "parent.child4"]
    }
  },
  methods: {
    // updateContainerHeight() {
    //   const container = this.$refs.container;
    //   const content = this.$refs.content;

    //   // 更新容器的高度
    //   container.style.height = `${content.scrollHeight}px`;
    // },
    // 渲染节点内容
    // 使用一个单独的数据属性来记录当前悬停的元素。
    // 在 mouseover 和 mouseout 事件中更新这个数据属性。
    // 在 CSS 中使用动态类来控制 tooltip 的显示
  renderContent(h, { node, data, store }) {
    // 判断是否显示tooltip
    const tooltipElement = this.currentTooltipNode === node ? (
      h('span', 
        { 
          class: ['tooltip', { 'show-tooltip': this.showTooltip}],
          style: {
            backgroundColor: '#f00',
            left: `${this.tooltipPosition.x}px`,
            top: `${this.tooltipPosition.y}px`,
          },
        }, this.tooltipText)
      ) : null;
    // vue模版语法
    return h(
      'span',
      null,
      [
        data.required === '1' && h('span',{ style: { color: 'red', marginLeft: '5px', marginRight: '5px' } }, '*'),
        data.code && h('span', null, `${data.code} `),
        h(
          'span',
          {
              class: 'ellipsis',
              on: {
                mouseover: (event) => this.handleShowTooltip(event, node, data.name),
                mouseout: () => this.handleHideTooltip(),
              },
          },
          [data.name, tooltipElement]

        ),
        data.type && h('span', null, ` (${data.type})`)
      ].filter(Boolean)
    )


    // JSX语法
    // return (
    //   <span>
    //     {data.required === '1' && <span style="color: red;margin-left:5px;margin-right:5px;">*</span> }
    //     {data.code && <span>{data.code}&nbsp;&nbsp;</span> }
    //     <span 
    //       class="ellipsis" 
    //       onMouseover={(event)=> this.showToolTip(event,data.name)}
    //       onMouseOut={() => this.hideTooltip()}
    //     >
    //     {data.name}
    //     </span>
    //     {data.type && <span>({data.type})</span>}
    //   </span>
    // );
  },
  // TODO 浮动有bug
  handleShowTooltip(event,node,name) {
    this.tooltipText = name;
      // 获取左侧属性盒子的宽度
      const tooltipWidth = 300; // 假设 tooltip 宽度为 200px
      const tooltipHeight = 30; // 假设 tooltip 高度为 30px

      // 获取父级元素相对于视口的位置
      const treeContainer = this.$refs.tree.$el;
      const treeRect = treeContainer.getBoundingClientRect();

      // 计算相对于父级元素的坐标
      const x = Math.round(event.clientX - treeRect.left);
      const y =Math.round(event.clientY - treeRect.top - 20); // 初始 Y 坐标，假设 tooltip 显示在上方

      // console.log('x',x);
      // console.log('y',y);
      // console.log('‘leftBoxWidth', this.leftBoxWidth);

      if (x + tooltipWidth  > this.leftBoxWidth) {
        // 如果 tooltip 放在右侧会超出容器宽度，则放在下方
        this.tooltipPosition = { x: x , y: y+ tooltipHeight };
      } else {
        this.tooltipPosition = { x: x, y: y };
      }
      // console.log('this.tooltipPosition',this.tooltipPosition);
      
    this.currentTooltipNode = node;
    this.showTooltip = true;
  },
  handleHideTooltip() {
      this.currentTooltipNode = null;
      this.showTooltip = false;
  },
  handleNodeClick(node) {
    // console.log('节点点击事件----------1:', node);
  },
  handleCheck(node, checkedNodes) {
      const { checkedKeys, checkedNodes: checkedNodeList , halfCheckedNodes, halfCheckedKeys } = checkedNodes;
      console.log('checkedNodes', checkedNodes)
      // this.getCheckedNodesWithParents(this.treeData, checkedKeys)
      //  this.processData(this.treeData, checkedKeys)
      const result = this.generateNewTreeNodes(this.treeData, checkedKeys)
      console.log('result',result);
      console.log('visitObj', this.visitObj);
    },  
    getCheckedNodesWithParents(treeData, checkedKeys) {
    const result = [];

    function traverse(data, parent = null) {
        const currentNode = {...data };
        if (checkedKeys.includes(currentNode.nodePath)) {
            if (parent) {
                currentNode.parent = {...parent };
            }
            result.push(currentNode);
        }
        if (currentNode.children) {
            for (const child of currentNode.children) {
                traverse(child, currentNode);
            }
        }
    }

    traverse(treeData[0], null);
    console.log('result',result);
    
    return result;
},
processData(treeData, checkedKeys) {
  const result = [];

  for (const node of treeData) {
    const newNode = {...node };
    newNode.children = [];

    if (checkedKeys.includes(node.nodePath)) {
      for (const child of node.children || []) {
        if (checkedKeys.includes(child.nodePath)) {
          if (child.children) {
            for (const grandChild of child.children) {
              if (checkedKeys.includes(grandChild.nodePath)) {
                newNode.children.push({...grandChild });
              }
            }
          }
          newNode.children.push({...child });
        }
      }
    }
    result.push(newNode);
  }
  console.log('result',result);
  return result;
},
generateNewTreeNodes(treeData, checkedKeys) {
  this.ret = {};
  this.visitObj = {};
  console.log('checkedKeys', checkedKeys);

  for (let key of checkedKeys) {
    if (this.leafNodes.includes(key)) {
      this.generateNewTreeNode(treeData, key);
    }
  }

  let levelNode = {}
  let newTree = {};
  let sortedKeys = Object.keys(this.visitObj).sort((a, b) => {
    return a.split(";")[1] - b.split(";")[1];
  });
  console.log("sortedKeys", sortedKeys);
  console.log("visiObje", this.visitObj);
  let tmpTree = {};
  for (let key of sortedKeys) {
    let allKey = key.split(";");
    let code = allKey[0];
    let level = allKey[1];
    let p = allKey[2];
    if (p == "") [
      this.newTree = {...this.visitObj[key], children: []}
    ]
    // let tmp2 = this.generateParentNodes(this.newTree, p, this.visitObj[key]);
    // this.newTree = tmp2;
    // console.log("newTree1", tmp2);
    // if (this.newTree[p]) {
    //   this.newTree[p].childrenpush({...this.visitObj[key], children: []});
    // }
  }
  console.log("this.newTree", this.newTree);

},
// generateParentNodes(newTree, p, item) {
//   if (JSON.stringify(newTree) === '{}') {
//     newTree = {...item, children:[]};
//     return newTree;
//   }
//   if (!newTree) {
//     return undefined;
//   }
//   if (newTree.nodePath == p) {
//     newTree.children.push({...item, children: []});
//     return newTree;
//   } else {
    
//     for (let child of newTree.children) {
//       let tmp = this.generateParentNodes(child, p, item);
//     }
//   }
//   return newTree;
  
// },
generateNewTreeNode(treeData, checkedKey) {
  let newItem = {};
  console.log('checkedKeys---------------1',checkedKey);
  for (let item of treeData) {
    if (checkedKey.includes(item.nodePath)) {
      newItem = {...item, children:[]};
      let node = this.generateNewTreeNode(item.children || [], checkedKey);
      if (JSON.stringify(node) != '{}') {
        newItem.children.push(node);
      }
      let nodePaths = item.nodePath.split(".");
      let p;
      if (nodePaths.length > 1) {
        p = nodePaths.splice(0, nodePaths.length - 1).join(".");
      } else {
        p = "";
      }
      if (!this.visitObj[item.code + ";" + item.level + ";" + p]) {
        this.visitObj[this.generateNodeKey(item.code, item.level, p)] = newItem; 
      }
    }
  }
  console.log('newTree',newItem);
  return newItem;
},
generateNodeKey(code, level, p) {
  return code + ";" + level + ";" + p;
},
  // 递归全选或取消全选所有子节点
  checkAllChildren(node, checked) {
    if (node.data.children) {
      node.data.children.forEach(child => {
        this.$refs.tree.check(child, checked, false); // 选中子节点
        if (child.children) {
          this.checkAllChildren(child, checked);
        }
      });
    }
    },
  // 收集选中的节点数据
  // 需要包含父节点和子节点的数据  TODO？？？
  // 是否需要加入新的字段？？？
  // "maxLen": 1."rule ""checkRule":"fil1Rule": "fi11","fillValue": "fi11"
  // collectSelectedData() {
  //   const selectedData = [];
  //   this.$refs.tree.getCheckedNodes().forEach(node => {
  //     selectedData.push({
  //       code: node.code,
  //       name: node.name,
  //       required: node.required,
  //       type: node.type,
  //       maxLen: node.maxLen ? node.maxLen : '',
  //       checkRule: node.checkRule ? node.checkRule : '',//校验规则
  //       fillRule: node.fillRule ? node.fillRule : '',//填充规则
  //       fillValue: node.fillValue ? node.fillValue : '',//填充值
  //       // children: node.children ? this.collectSelectedData(node.children) : null
  //     });
  //   });
  //   console.log('selectedData----选择的数据',selectedData);
    
  //   return selectedData;
  // },

  getLeftBoxWidth() {
      const leftBox = document.querySelector('.elTreeClass');
      this.leftBoxWidth = leftBox.offsetWidth;
      // console.log('Left Box Width:', this.leftBoxWidth);
  },
  // 处理右边table
    handleCheckboxChange(row, value) {
      // console.log(`Row ${row.id} checkbox changed to: ${value}`);
      // 可以在这里处理其他逻辑，例如更新数据库或状态
    }
  },
  mounted() {
    // this.updateContainerHeight();
    // new MutationObserver(this.updateContainerHeight).observe(
    //   this.$refs.content,
    //   {
    //     childList: true,
    //     subtree: true
    //   }
    // );
    this.getLeftBoxWidth();
  },
  created() {
    // created 钩子中使用 bind 方法来确保 showTooltip 和 hideTooltip 方法绑定到组件实例
    this.handleShowTooltip = this.handleShowTooltip.bind(this)
    this.handleHideTooltip = this.handleHideTooltip.bind(this);
    // TODO 每个节点加一个id
    // this.processTreeData(treeDataFromBackend);
  },


  // 
}
</script>

<style lang="less">
  .container {
    width: 100%; /* 容器宽度设为 100% 或者具体数值 */
    max-width: 100%; /* 最大宽度设为 100%，防止过宽 */
    overflow-y: auto; /* 当内容超过容器高度时，出现垂直滚动条 */
    height: 100vh; /* 高度设为视口高度，可以根据需要调整 */
  /* 自定义滚动条样式 */
    scrollbar-width: thin; /* Firefox */
    &::-webkit-scrollbar { /* Chrome, Safari, and Edge */
      width: 8px; /* 滚动条宽度 */
    }
    &::-webkit-scrollbar-track {
      background: #f1f1f1; /* 轨道背景颜色 */
    }
    &::-webkit-scrollbar-thumb {
      background: #888; /* 滚动条颜色 */
    }
    &::-webkit-scrollbar-thumb:hover {
      background: #555; /* 滚动条悬停颜色 */
    }
  }
  .content {
    display: flex; /* 使用 Flex 布局 */
    flex-wrap: wrap; /* 内容换行 */
    gap: 1rem; /* 子元素之间的间距 */
  }
  .elTreeClass {
    flex: 1;
    // TODO新加的
    position: relative;
    background-color: lightblue;
  }
  .elTableClass {
    flex: 2; /* 占据 2 份空间 */
    background-color: lightgreen;
  }
  .el-tree {
    scrollbar-width: thin; /* Firefox */
    &::-webkit-scrollbar { /* Chrome, Safari, and Edge */
    width: 8px; /* 滚动条宽度 */
  }
  &::-webkit-scrollbar-track {
    background: #f1f1f1; /* 轨道背景颜色 */
  }
  &::-webkit-scrollbar-thumb {
    background: #888; /* 滚动条颜色 */
  }
  &::-webkit-scrollbar-thumb:hover {
    background: #555; /* 滚动条悬停颜色 */
  }
  .ellipsis {
    display: inline-block;
    max-width: 150px; /* 可以根据需要调整 */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: top;
  }

  .tooltip {
    position: absolute;
    background-color: #dcdfe6;
    color: #fff;
    border-radius: 4px;
    z-index: 1000;
    visibility: hidden;
  }

  .show-tooltip {
    visibility: visible;
  }
}
</style>